package com.tancire.net.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.tancire.common.core.domain.entity.SysUser;
import com.tancire.common.core.redis.RedisCache;
import com.tancire.common.enums.OrderStatus;
import com.tancire.common.enums.PayStatus;
import com.tancire.common.exception.net.NetActivityException;
import com.tancire.common.utils.DateUtils;
import com.tancire.common.utils.SecurityUtils;
import com.tancire.common.utils.StringUtils;
import com.tancire.net.domain.*;
import com.tancire.net.mapper.OrderInfoMapper;
import com.tancire.net.service.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import static com.tancire.common.constant.Constants.GOODS_STOCK_PREFIX;

/**
 * 订单管理Service业务层处理
 *
 * @author chenchao
 * @date 2023-11-29
 */
@Service
public class OrderInfoServiceImpl implements IOrderInfoService {

    @Resource
    private OrderInfoMapper orderInfoMapper;

    @Resource
    private IOrderDetailService orderDetailService;

    @Resource
    private IOrderLogService orderLogService;

    @Resource
    private IShopGoodsService shopGoodsService;

    @Resource
    private IPurseInfoService purseInfoService;

    @Resource
    private IAuthInfoService authInfoService;

    @Resource
    private RedisCache redisCache;

    /**
     * 查询订单管理
     *
     * @param id 订单管理主键
     * @return 订单管理
     */
    @Override
    public OrderInfo selectOrderInfoById(Long id) {
        return orderInfoMapper.selectOrderInfoById(id);
    }

    /**
     * 查询订单管理列表
     *
     * @param orderInfo 订单管理
     * @return 订单管理
     */
    @Override
    public List<OrderInfo> selectOrderInfoList(OrderInfo orderInfo) {
        return orderInfoMapper.selectOrderInfoList(orderInfo);
    }

    /**
     * 新增订单管理
     *
     * @param orderInfo 订单管理
     * @return 结果
     */
    @Override
    public int insertOrderInfo(OrderInfo orderInfo) {
        orderInfo.setCreateTime(DateUtils.getNowDate());
        return orderInfoMapper.insertOrderInfo(orderInfo);
    }

    /**
     * 修改订单管理
     *
     * @param orderInfo 订单管理
     * @return 结果
     */
    @Override
    public int updateOrderInfo(OrderInfo orderInfo) {
        orderInfo.setUpdateTime(DateUtils.getNowDate());
        return orderInfoMapper.updateOrderInfo(orderInfo);
    }

    /**
     * 批量删除订单管理
     *
     * @param ids 需要删除的订单管理主键
     * @return 结果
     */
    @Override
    public int deleteOrderInfoByIds(Long[] ids) {
        return orderInfoMapper.deleteOrderInfoByIds(ids);
    }

    /**
     * 删除订单管理信息
     *
     * @param id 订单管理主键
     * @return 结果
     */
    @Override
    public int deleteOrderInfoById(Long id) {
        return orderInfoMapper.deleteOrderInfoById(id);
    }

    /**
     * 下单
     * 自动扣积分
     *
     * @param orderInfo
     * @return
     */
    @Transactional
    @Override
    public int addOrder(OrderInfo orderInfo) {
        // 暂时不加锁，数量上仅做弱校验
        // 获取兑换商品
        List<OrderDetail> detailList = orderInfo.getDetailList();
        try {
            // 所需积分
            BigDecimal totalFen = BigDecimal.ZERO;
            // 校验库存
            for (OrderDetail goods : detailList) {
                Integer buyCount = goods.getBuyCount();
                if (null == buyCount && buyCount < 1) {
                    throw new NetActivityException("兑换商品数量不能为空");
                }
                // 获取商品数量
                int count = this.getGoodsStock(goods.getGoodsId());
                if (count >= buyCount && count > 0) {
                    count = count - buyCount;
                    // 保存回去
                    redisCache.setCacheObject(GOODS_STOCK_PREFIX + goods.getGoodsId(), String.valueOf(count));
                    // 保存扣除数量
                    goods.setSubCount(buyCount);
                } else {
                    throw new NetActivityException("商品库存不足");
                }
                // 查询商品需要积分
                ShopGoods shopGoods = this.shopGoodsService.selectShopGoodsById(goods.getGoodsId());
                BigDecimal goodsFenPrice = shopGoods.getGoodsFenPrice();
                if (null == goodsFenPrice) {
                    goodsFenPrice = BigDecimal.ZERO;
                }
                BigDecimal totalPrice = goodsFenPrice.multiply(new BigDecimal(String.valueOf(buyCount)));
                totalFen = totalFen.add(totalPrice);
                goods.setGoodsName(shopGoods.getGoodsName());
                goods.setGoodsPrice(shopGoods.getGoodsFenPrice());
                goods.setTotalAmount(totalPrice);
                goods.setGoodsPic(shopGoods.getThumbnailPic());
            }
            // 扣完库存，扣积分
            Long userId = SecurityUtils.getLoginUser().getUserId();
            if (totalFen.compareTo(BigDecimal.ZERO) > 0) {
                purseInfoService.subPoints(userId, totalFen, "积分兑换扣除");
            }
            // 生成订单明细
            orderInfo.setOrderPrice(totalFen);
            orderInfo.setPayAmount(totalFen);
            this.generateOrder(orderInfo);
            // 记录日志
            this.saveLog(orderInfo);
        } catch (Exception e) {
            // 出现异常归还库存，抛出异常
            for (OrderDetail goods : detailList) {
                Integer subCount = goods.getSubCount();
                if (null != subCount) {
                    // 获取商品数量
                    int count = this.getGoodsStock(goods.getGoodsId());
                    if (count > 0) {
                        count = count +subCount ;
                        // 保存回去
                        redisCache.setCacheObject(GOODS_STOCK_PREFIX + goods.getGoodsId(), String.valueOf(count));
                    }
                }
            }
            throw new NetActivityException(e.getMessage());
        }
        return 1;
    }

    /**
     * 查询当前会员订单列表
     *
     * @param orderInfo
     * @return
     */
    @Override
    public List<OrderInfo> selectUserOrderList(OrderInfo orderInfo) {
        // 当前登录用户
        Long userId = SecurityUtils.getLoginUser().getUserId();
        if (null == userId) {
            throw new NetActivityException("获取兑换记录失败");
        }
        orderInfo.setUserId(userId);
        return this.orderInfoMapper.selectUserOrderList(orderInfo);
    }

    /**
     * 订单使用
     *
     * @param authDetail
     * @return
     */
    @Transactional
    @Override
    public AuthDetail useOrder(AuthDetail authDetail) {
        // 获取订单信息
        OrderInfo orderInfo = this.orderInfoMapper.selectOrderInfoById(Long.parseLong(authDetail.getOrderId()));
        String orderStatus = orderInfo.getOrderStatus();
        if (OrderStatus.NOT_USE.getCode().equals(orderStatus)) {
            OrderDetail query = new OrderDetail();
            query.setOrderId(orderInfo.getId());
            List<OrderDetail> orderDetails = this.orderDetailService.selectOrderDetailList(query);

            if (ObjectUtil.isNotEmpty(orderDetails)) {
                OrderDetail detail = orderDetails.get(0);

                String sourceName = authDetail.getSourceName();
                if (detail.getGoodsName().equals(sourceName) || "任意软件免费激活码".equals(sourceName)) {
                    // 标记订单已使用
                    OrderInfo upOrder = new OrderInfo();
                    upOrder.setId(orderInfo.getId());
                    upOrder.setOrderStatus(OrderStatus.USED.getCode());
                    this.orderInfoMapper.updateOrderInfo(upOrder);
                    // 获取激活码
                    return this.authInfoService.authByCode(authDetail, false);
                } else {
                    throw new NetActivityException("未匹配到资源信息");
                }
            } else {
                throw new NetActivityException("未查询到订单信息");
            }
        } else {
            throw new NetActivityException("当前订单状态不能使用");
        }
    }

    /**
     * 保存订单日志
     *
     * @param orderInfo
     */
    private void saveLog(OrderInfo orderInfo) {
        OrderLog orderLog = new OrderLog();
        SysUser user = SecurityUtils.getLoginUser().getUser();
        String nickName = user.getNickName();
        if (StringUtils.isBlank(nickName)) {
            nickName = "微信用户";
        }

        orderLog.setOrderId(orderInfo.getId());
        orderLog.setOrderCode(orderInfo.getOrderCode());
        orderLog.setCreateBy(String.valueOf(user.getUserId()));
        orderLog.setCreateByName(nickName);
        orderLog.setCreateTime(new Date());
        orderLog.setSysFlag(user.getUserSource());
        // 拼装描述
        orderLog.setLogRemark(nickName + "兑换商品下单");
        this.orderLogService.insertOrderLog(orderLog);
    }

    /**
     * 构建订单明细
     *
     * @param orderInfo
     */
    private void generateOrder(OrderInfo orderInfo) {
        Date current = new Date();
        // 生成ID
        long orderId = IdUtil.getSnowflakeNextId();
        orderInfo.setId(orderId);
        // 获取订单号
        String orderCode = this.genOrderCode();
        orderInfo.setOrderCode(orderCode);
        // 标记订单状态 为待使用
        orderInfo.setOrderStatus(OrderStatus.NOT_USE.getCode());
        // 处理会员信息
        SysUser user = SecurityUtils.getLoginUser().getUser();
        orderInfo.setUserId(user.getUserId());
        orderInfo.setUserName(user.getNickName());
        // 标记已支付
        orderInfo.setPayStatus(PayStatus.PAYED.getCode());
        orderInfo.setPayTime(current);
        // 处理订单创建人信息
        orderInfo.setCreateBy(String.valueOf(user.getUserId()));
        orderInfo.setCreateTime(new Date());
        // 处理订单明细
        List<OrderDetail> detailList = orderInfo.getDetailList();
        if (ObjectUtil.isNotEmpty(detailList)) {
            for (OrderDetail detail : detailList) {
                // 生成ID
                detail.setId(IdUtil.getSnowflakeNextId());
                // 保存订单ID
                detail.setOrderId(orderId);
                detail.setOrderCode(orderCode);
                detail.setCreateBy(String.valueOf(user.getUserId()));
                detail.setCreateTime(current);
            }
        }
        // 保存数据
        this.orderInfoMapper.insertOrderInfo(orderInfo);
        // 保存明细
        this.orderDetailService.saveBatch(detailList);
    }

    /**
     * 生成订单号
     *
     * @return
     */
    private String genOrderCode() {
        int randomInt = RandomUtil.randomInt(999999);
        String randomStr = randomInt + "";
        int length = randomStr.length();
        int x = 6 - length;
        if (x > 0) {
            for (int i = 0; i < x; i++) {
                randomStr = "0" + randomStr;
            }
        }
        long time = new Date().getTime();
        return time + randomStr;
    }

    /**
     * 获取库存数量
     *
     * @param goodsId
     * @return
     */
    private int getGoodsStock(Long goodsId) {
        Object cacheObject = redisCache.getCacheObject(GOODS_STOCK_PREFIX + goodsId);
        if (null != cacheObject) {
            try {
                int count = Integer.parseInt((String) cacheObject);
                return count;
            } catch (Exception e) {
                // 不处理
            }
        }
        return 0;
    }
}
